#include "ShareMemory.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/shm.h>

struct ShareMemory
{
    key_t key;
    int shmid;
    void *data;
    size_t size;
};

ShMemory *InitShareMemory(const char *pathname, int pro_id, size_t size)
{
    ShMemory *m=(ShMemory*)malloc(sizeof(ShMemory));
    if(m==NULL)
    {
        printf("InitShareMemory malloc error\n");
        return NULL;
    }
    m->key=ftok(pathname,pro_id);
    if(m->key<0)
    {
        perror("ftok");
        free(m);
        return NULL;
    }
    m->size=size;
    m->shmid=shmget(m->key,1024,IPC_CREAT|0777);
    if(m->shmid<0)
    {
        perror("shmget");
        free(m);
        return NULL;
    }
    return m;
}

void ReadFormShareMemory(ShMemory *m, void *ptr, size_t size)
{
    if(size>m->size)
    {
        printf("this is bigger than ShareMemory\n");
        return;
    }
    void *text=shmat(m->shmid,NULL,0);
    if(text==(void*)-1)
    {
        perror("shmat");
        return;
    }
    memcpy(ptr,text,size);
    if(shmdt(text)==-1)
    {
        perror("shmdt");
        return;
    }
}

void WriteToShareMemory(ShMemory *m, void *ptr, size_t size)
{
    if(size>m->size)
    {
        printf("this is bigger than ShareMemory\n");
        return;
    }
    void *text=shmat(m->shmid,NULL,0);
    if(text==(void*)-1)
    {
        perror("shmat");
        return;
    }
    memcpy(text,ptr,size);
    if(shmdt(text)==-1)
    {
        perror("shmdt");
        return;
    }
}

void ClearShareMemory(ShMemory *m)
{
    if(shmctl(m->shmid,IPC_RMID,NULL)==-1)
    {
        perror("ClearShareMemory");
    }
    free(m);
    m=NULL;
}
